#############################################################
# File: assemble.py
# Function: Assemble variational problem with Dolfin (http://www.fenicsproject.org/)
# Author: Bruno Luna
# Date: 03/02/11
# Modifications Date:
# 
#
#
#
#
#############################################################
from dolfin import *

def assemble_elliptic():
    """Assembles the elliptic problem variational form with Dolfin."""  
    
    # Defining linear algebra package to be used (Petsc, uBlas, etc.)
    parameters.linear_algebra_backend = "uBLAS"
    
    # Read mesh from file and create function space
    mesh = UnitSquare(256,256)
    V = FunctionSpace(mesh, "CG", 1)
    
    # Define Dirichlet boundary (x = 0 or x = 1 or y = 0 or y = 1)
    def boundary(x):
        return x[0] < DOLFIN_EPS or x[0] > 1.0 - DOLFIN_EPS or \
               x[1] < DOLFIN_EPS or x[1] > 1.0 - DOLFIN_EPS
    
    # Define boundary condition
    u0 = Expression('exp(x[0]*x[1])')
    bc = DirichletBC(V, u0, boundary)
    
    # Define conductivity matrix
    C = as_matrix(((2.0, 1.0), (1.0, 2.0)))
    
    # Define variational problem
    v = TestFunction(V)
    u = TrialFunction(V)
    f = Expression("- 2*(1 + pow(x[0],2) + x[0]*x[1] + pow(x[1],2))*exp(x[0]*x[1])")
    a = inner(grad(v), C*grad(u))*dx
    L = v*f*dx
    
    # Assemble matrices and vectors
    A, rhs = assemble_system(a, L, bc)
    
    return V,  A,  rhs,  u0
############################################################
